package com.example.photo.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.photo.common.AuthCheck;
import com.example.photo.common.BaseResponse;
import com.example.photo.common.ErrorCode;
import com.example.photo.constant.ContestStatus;
import com.example.photo.exception.BusinessException;
import com.example.photo.model.VO.ContestVO;
import com.example.photo.model.VO.PrizeVO;
import com.example.photo.model.domain.Contest;
import com.example.photo.model.request.add.NewContestRequest;
import com.example.photo.model.request.update.UpdateContestRequest;
import com.example.photo.service.ContestService;
import com.example.photo.service.PrizeService;
import com.example.photo.utils.ResultUtils;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 赛事管理接口
 *
 * @author Lwh
 * @time 2023/03/29 16:06
 */
@RestController
@RequestMapping("/contest")
public class ContestController {
    @Resource
    private ContestService contestService;

    @Resource
    private PrizeService prizeService;

    /**
     * 管理员新建赛事
     */
    @AuthCheck
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
    @PostMapping("/create")
    public BaseResponse<ContestVO> createContest(@RequestBody NewContestRequest newContestRequest) {
        if (newContestRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数不能为空");
        }
        ContestVO contestVO = contestService.newContest(newContestRequest);
        if (contestVO == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "新建比赛失败");
        }

        Integer contestId = contestVO.getContestId();
        List<Integer> prizeIds = newContestRequest.getPrizeIds();
        //奖项id列表不为空，则保存赛事id到这些奖项的信息中
        if (prizeIds.size() != 0) {
            prizeService.setContestForPrizes(prizeIds, contestId);
        }
        //获取奖项map
        Map<Integer, List<PrizeVO>> map = prizeService.getPrizesByContestId(contestId);
        contestVO.setPrizes(map);
        return ResultUtils.success(contestVO);
    }

    /**
     * 管理员更新赛事信息
     */
    @AuthCheck
    @PostMapping("/update")
    public BaseResponse<ContestVO> updateContest(@RequestBody UpdateContestRequest updateContestRequest) {
        if (updateContestRequest == null || updateContestRequest.getContestId() == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        contestService.updateContest(updateContestRequest);
        Integer contestId = updateContestRequest.getContestId();
        ContestVO contestVO = new ContestVO(contestService.getById(contestId));
        //获取奖项map
        Map<Integer, List<PrizeVO>> map = prizeService.getPrizesByContestId(contestId);
        contestVO.setPrizes(map);
        return ResultUtils.success(contestVO);
    }

    /**
     * 根据id获取赛事信息
     */
    @GetMapping("/get")
    public BaseResponse<ContestVO> getContestById(@RequestParam Integer contestId) {
        if (contestId < 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Contest contest = contestService.getById(contestId);
        if (contest == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "查询的赛事信息不存在");
        }
        ContestVO contestVO = new ContestVO(contest);
        //获取奖项map
        Map<Integer, List<PrizeVO>> prizeMap =  prizeService.getPrizesByContestId(contestId);
        contestVO.setPrizes(prizeMap);
        return ResultUtils.success(contestVO);
    }

    /**
     * 获取当前赛事总数
     */
    @GetMapping("/count")
    public BaseResponse<Long> countContest() {
        return ResultUtils.success(contestService.count());
    }

    /**
     * 查看所有的赛事信息（往届赛事）
     * （分页查询）
     */
    @GetMapping("/list")
    public BaseResponse<List<ContestVO>> listContest(@RequestParam long pageSize,
                                                     @RequestParam long pageNum) {
        QueryWrapper<Contest> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("start_time");
        List<ContestVO> list =
                contestService.page(new Page<>(pageNum, pageSize), wrapper)
                        .getRecords().stream()
                        .map(ContestVO::new)
                        .collect(Collectors.toList());
        return ResultUtils.success(list);
    }

    /**
     * 查询最新正在进行的赛事
     */
    @GetMapping("/running")
    public BaseResponse<ContestVO> listRunningContest() {
        QueryWrapper<Contest> wrapper = new QueryWrapper<>();
        wrapper.eq("status", ContestStatus.ONGOING);
        wrapper.orderByDesc("start_time");
        wrapper.last("limit 1");
        Contest contest = contestService.getOne(wrapper);
        Map<Integer, List<PrizeVO>> map = prizeService.getPrizesByContestId(contest.getContestId());
        ContestVO contestVO = new ContestVO(contest);
        contestVO.setPrizes(map);
        return ResultUtils.success(contestVO);
    }

    /**
     * 管理员删除赛事
     */
    @AuthCheck
    @PostMapping("/remove")
    public BaseResponse<Boolean> removeContest(@RequestParam Integer contestId) {
        if (contestId < 1) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        boolean remove = contestService.removeById(contestId);
        if (!remove) {
            throw new BusinessException(ErrorCode.SERVER_ERROR, "删除赛事信息失败");
        }
        return ResultUtils.success(true);
    }

}
